package org.cleverframe.fastdfs.pool;

import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import org.apache.commons.pool2.BasePooledObjectFactory;
import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.impl.DefaultPooledObject;
import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;


public class FtpClientPool {
    private static final String SERVER = "10.10.180.176";
    private static final int PORT = 21;
    private static final String USERNAME = "ftp176";
    private static final String PASSWORD = "FTP176";

    private GenericObjectPool<FTPClient> pool;

    public FtpClientPool(GenericObjectPoolConfig config) {
        this.pool = new GenericObjectPool<>(new FtpClientFactory(), config);
    }

    public FTPClient borrowFtpClient() throws Exception {
        return pool.borrowObject();
    }

    public void returnFtpClient(FTPClient client) {

        pool.returnObject(client);
    }


    public void close() {
        pool.close();
    }


    private static class FtpClientFactory extends BasePooledObjectFactory<FTPClient> {
        private static final Logger log = LoggerFactory.getLogger(FtpClientFactory.class);
        @Override
        public FTPClient create() throws Exception {
            FTPClient ftpClient = new FTPClient();

            ftpClient.setRemoteVerificationEnabled(false);
            ftpClient.setConnectTimeout(6000);
            ftpClient.setDataTimeout(6000);
            ftpClient.enterLocalPassiveMode();

            ftpClient.setControlEncoding("UTF-8");
            ftpClient.setControlKeepAliveTimeout(300);

            try {

                ftpClient.connect(SERVER, PORT);
                boolean login = ftpClient.login(USERNAME, PASSWORD);
                if (!login){
                    System.out.println("login:" + login);
                }


                int replyCode = ftpClient.getReplyCode();
                if (!FTPReply.isPositiveCompletion(replyCode)) {
                    ftpClient.disconnect();
                    log.warn("ftpServer refused connection,replyCode:{}", replyCode);
                    return null;
                }

//                ftpClient.setBufferSize(1024);
                ftpClient.setFileType(FTP.BINARY_FILE_TYPE);

            } catch (IOException e) {
                log.error("create ftp connection failed...", e);
            }


            return ftpClient;
        }

        @Override
        public PooledObject<FTPClient> wrap(FTPClient ftpClient) {
            return new DefaultPooledObject<>(ftpClient);
        }

        @Override
        public void destroyObject(PooledObject<FTPClient> p) throws Exception {
            FTPClient ftpClient = p.getObject();
            if (ftpClient.isConnected()) {
                ftpClient.logout();
                ftpClient.disconnect();
            }
        }

        @Override
        public boolean validateObject(PooledObject<FTPClient> p) {
            FTPClient ftpClient = p.getObject();
            return ftpClient.isConnected();
        }
    }
}
